home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-22 | 34.8 KB | 1,076 lines |
- // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
- // see COPYRIGHT for reuse legalities
- //
-
- #import "RIBCommand.h"
- #import "WWEveParser.h" // for the WW_ defines...
- #import "WWSceneClock.h"
- #import "WW3DAttributeState.h"
- #import <stdio.h>
-
- @implementation RIBCommand
-
- + initialize { return [RIBCommand setVersion:1], self; }
-
- - init
- {
- [super init];
-
- n = 0;
- tokens = (RtToken *)NULL;
- parms = (RtPointer *)NULL;
- archiveVector = (char **)NULL;
- printfNVector = (int *)NULL;
- printfTypeVector = (int *)NULL;
-
- dirtyBoundingBox = TRUE;
-
- return self;
- }
-
-
- - awake
- {
- [super awake];
-
- dirtyBoundingBox = TRUE;
-
- return self;
- }
-
-
- - (void)setN:(int)newN tokens:(RtToken *)newTokens parms:(RtPointer *)newParms archiveVector:(char **)newArchiveVector printfTypeVector:(int *)newPrintfTypeVector printfNVector:(int *)newPrintfNVector
- {
- int i;
-
-
- if (n)
- { for (i = 0; i < n; i++)
- { // don't free the tokens; they're shared!
- free(parms[i]);
- free(archiveVector[i]);
- free(printfNVector);
- free(printfTypeVector);
- }
- if (newN > n)
- { tokens = (RtToken *)NXZoneRealloc([self zone], tokens, (newN * sizeof(RtToken)));
- parms = (RtPointer *)NXZoneRealloc([self zone], parms, (newN * sizeof(RtPointer)));
- archiveVector = (char **)NXZoneRealloc([self zone], archiveVector, (newN * sizeof(archiveVector)));
- printfNVector = (int *)NXZoneRealloc([self zone], printfNVector, (newN * sizeof(int)));
- printfTypeVector = (int *)NXZoneRealloc([self zone], printfTypeVector, (newN * sizeof(int)));
- }
- }
- else
- { tokens = (RtToken *)NXZoneMalloc([self zone], newN * sizeof(RtToken));
- parms = (RtPointer *)NXZoneMalloc([self zone], newN * sizeof(RtPointer));
- archiveVector = (char **)NXZoneMalloc([self zone], newN * sizeof(archiveVector));
- printfNVector = (int *)NXZoneMalloc([self zone], newN * sizeof(int));
- printfTypeVector = (int *)NXZoneMalloc([self zone], newN * sizeof(int));
- }
- n = newN;
- for (i = 0; i < n; i++)
- { tokens[i] = newTokens[i];
- parms[i] = newParms[i];
- archiveVector[i] = newArchiveVector[i];
- printfNVector[i] = newPrintfNVector[i];
- printfTypeVector[i] = newPrintfTypeVector[i];
- }
-
- dirtyBoundingBox = TRUE;
- return ;
- }
-
- - free
- {
- int i;
-
-
- //NXLogError("%s %d being free'ed\n", [[self class] name], self);
- // don't free the tokens; they're constants (i.e. RI_P, RI_PW, etc.)
- //NXLogError("RIBCommand %s: freeing %p", [[self class] name], self);
- for (i = 0; i < n; i++)
- { if (parms[i]) { free(parms[i]); }
- if (archiveVector[i]) { free(archiveVector[i]); }
- }
- if (n)
- { if (printfNVector) { free(printfNVector); }
- if (printfTypeVector) { free(printfTypeVector); }
- }
- return [super free];
- }
-
- // this should only be called internally
- // the receiving object needs to copy all the parameters using the passed in zone
- // the assumption is that
- - _mallocPointersUsingZone:(NXZone *)zone
- {
- if (n)
- { tokens = (RtToken *)NXZoneMalloc([self zone], n * sizeof(RtToken));
- if (!tokens)
- { return nil;
- }
- parms = (RtPointer *)NXZoneMalloc([self zone], n * sizeof(RtPointer));
- if (!parms)
- { NXZoneFree(zone, tokens);
- return nil;
- }
- archiveVector = (char **)NXZoneMalloc([self zone], n * sizeof(char *));
- if (!archiveVector)
- { NXZoneFree(zone, tokens);
- NXZoneFree(zone, parms);
- return nil;
- }
- printfNVector = (int *)NXZoneMalloc([self zone], n * sizeof(int));
- if (!printfNVector)
- { NXZoneFree(zone, tokens);
- NXZoneFree(zone, parms);
- NXZoneFree(zone, archiveVector);
- return nil;
- }
- printfTypeVector = (int *)NXZoneMalloc([self zone], n * sizeof(int));
- if (!printfTypeVector)
- { NXZoneFree(zone, tokens);
- NXZoneFree(zone, parms);
- NXZoneFree(zone, archiveVector);
- NXZoneFree(zone, printfNVector);
- return nil;
- }
- }
- else
- { // n == 0
- tokens = (RtToken *)NULL;
- parms = (RtPointer *)NULL;
- archiveVector = (char **)NULL;
- printfNVector = (int *)NULL;
- printfTypeVector = (int *)NULL;
- }
- return self;
- }
-
- - _setToken:(char *)newToken parm:(RtPointer)newParm i:(int)i archiveInfo:(char *)archiveInfo type:(int)parmType count:(int)howMany usingZone:(NXZone *)zone
- {
- int j;
-
-
- tokens[i] = (RtToken)NXZoneMalloc(zone, (1 + strlen(newToken)));
- if (!tokens[i])
- { return nil;
- }
- strcpy(tokens[i], newToken);
-
- archiveVector[i] = (char *)NXZoneMalloc(zone, (1 + strlen(archiveInfo)));
- if (!archiveVector[i])
- { NXZoneFree(zone, tokens[i]);
- return nil;
- }
- strcpy(archiveVector[i], archiveInfo);
-
- printfTypeVector[i] = parmType;
- printfNVector[i] = howMany;
-
- // in a perfect world, I could just copy that chunk o memory over,
- // but I'm worried about alignment problems, so I'll do it the slow way...
- switch (printfTypeVector[i])
- { case WW_FLOAT: parms[i] = (RtFloat *)NXZoneMalloc(zone, sizeof(RtFloat) * howMany);
- for (j = 0; j < printfNVector[i]; j++)
- { *((RtFloat *)parms[i] + j) = *((RtFloat *)(newParm) + j);
- }
- break;
- case WW_COLOR: parms[i] = (RtFloat *)NXZoneMalloc(zone, sizeof(RtFloat) * howMany);
- for (j = 0; j < printfNVector[i]; j++)
- { *((RtFloat *)parms[i] + j) = *((RtFloat *)(newParm) + j);
- }
- break;
- case WW_POINT: parms[i] = (RtFloat *)NXZoneMalloc(zone, sizeof(RtFloat) * howMany);
- for (j = 0; j < printfNVector[i]; j++)
- { *((RtFloat *)parms[i] + j) = *((RtFloat *)(newParm) + j);
- }
- break;
- case WW_INT: parms[i] = (int *)NXZoneMalloc(zone, sizeof(int) * howMany);
- for (j = 0; j < printfNVector[i]; j++)
- { *((int *)parms[i] + j) = *((int *)(newParm) + j);
- }
- break;
- // hmm, strings are weirder.
- case WW_STRING: parms[i] = (char **)NXZoneMalloc(zone, sizeof(char *) * howMany);
- for (j = 0; j < printfNVector[i]; j++)
- { // need to additionally malloc up some memory here, folks
- *((char **)parms[i] + j) = (char *)NXZoneMalloc(zone, (1 + strlen(*((char **)(newParm) + j))));
- strcpy(*((char **)parms[i] + j), *((char **)(newParm) + j));
- }
- break;
- }
- return self;
- }
-
-
- - copyFromZone:(NXZone *)zone
- {
- int i;
- id newCopy = [super copyFromZone:zone];
-
- // now we need to grovel over the parameters and copy them
- // this is a pain, but boy, will it be cool...
- // okay, malloc up the base list of pointers
- [newCopy _mallocPointersUsingZone:zone];
- for (i = 0; i < n; i++)
- { if (![newCopy _setToken:tokens[i] parm:parms[i] i:i
- archiveInfo:archiveVector[i] type:printfTypeVector[i] count:printfNVector[i]
- usingZone:zone])
- { [newCopy free];
- return nil;
- }
- }
-
- return newCopy;
- }
-
- - _lerpParametersWith:b by:(float)u
- {
- int i, j;
- RtToken *tokensB;
- char **archiveVectorB;
- int *printfNVectorB;
- int *printfTypeVectorB;
- RtPointer *parmsB;
-
-
- // okay, first thing to realize is that this instance already has its
- // parameters set to the (u ==0) case here. Therefore, when in doubt,
- // you can leave it alone and you're fine. We now want to grovel
- // over the two objects' parameters.
- if (n != [b n])
- { // hmm. looks like trouble. At some point, we'll have to bail,
- // since the parameter lists aren't the same length. we could
- // bail right away, since we know that "self"'s parameters are set
- // to something reasonable... Yea, let's bail.
- return self;
- }
-
- tokensB = [b tokens];
- archiveVectorB = [b archiveVector];
- printfNVectorB = [b printfNVector];
- printfTypeVectorB = [b printfTypeVector];
- parmsB = [b parms];
-
- // okay, at this point, we know that these two objects are the same
- // class, and the length of their parameter lists are the same. Of
- // course, this might be just a lucky coincidence, and the actual
- // parameters might be different types.
-
- for (i = 0; i < n; i++)
- { if ((tokens[i] == tokensB[i]) || (!strcmp(tokens[i], tokensB[i])))
- { // great! they're the same token.
- // now we need to make sure they're the same type and length of data
- // if not, bail to the next parameter
- if ((printfNVector[i] == printfNVectorB[i]) && (printfTypeVector[i] == printfTypeVectorB[i]))
- { // okay! we're golden. Let's do a lerp...
- switch (printfTypeVector[i])
- { case WW_FLOAT: for (j = 0; j < printfNVector[i]; j++)
- { *((RtFloat *)parms[i] + j) += ((*((RtFloat *)(parmsB[i]) + j) - *((RtFloat *)parms[i] + j)) * u);
- }
- break;
- case WW_COLOR: for (j = 0; j < printfNVector[i]; j++)
- { *((RtFloat *)parms[i] + j) += ((*((RtFloat *)(parmsB[i]) + j) - *((RtFloat *)parms[i] + j)) * u);
- }
- break;
- case WW_POINT: for (j = 0; j < printfNVector[i]; j++)
- { *((RtFloat *)parms[i] + j) += ((*((RtFloat *)(parmsB[i]) + j) - *((RtFloat *)parms[i] + j)) * u);
- }
- break;
- case WW_INT: for (j = 0; j < printfNVector[i]; j++)
- { *((int *)parms[i] + j) += ((*((int *)(parmsB[i]) + j) - *((int *)parms[i] + j)) * u);
- }
- break;
- case WW_STRING: // can't lerp strings without more info...
- // maybe could encode a way to do it with enumerated values, but for now, bail...
- break;
- }
- }
- else
- { // okay, that parameter can't be lerp'ed; on to the next
- }
- }
- else
- { // okay, that parameter can't be lerp'ed; on to the next
- }
- }
-
-
-
- return self;
- }
-
-
- // note: because we've made the WWSampleList "safe" for having
- // multiple samples with the same data, it's perfectly valid to return
- // yourself or b
- - lerpWith:b by:(float)uValue
- {
- id newMe = nil;
-
-
- if (([self class] != [b class]) || (uValue <= 0.0))
- { return self;
- }
-
- if (uValue >= 1.0)
- { return b;
- }
-
- newMe = [self copyFromZone:[self zone]];
-
- // okay, now we have to get newMe to linearly interpolate it
- // parameters partway between "self" and "b"
- [newMe _lerpParametersWith:b by:uValue];
-
- return newMe;
- }
-
- - lerpSelfWith:b by:(float)uValue
- {
- if (([self class] != [b class]) || (uValue <= 0.0))
- { return self;
- }
-
- if (uValue >= 1.0)
- { return b;
- }
-
- // okay, now we have to get newMe to linearly interpolate it
- // parameters partway between "self" and "b"
- [self _lerpParametersWith:b by:uValue];
-
- return self;
- }
-
- - (BOOL)pushesOrPopsCTM { return NO; }
- - (BOOL)pushesCTM { return NO; }
- - (BOOL)popsCTM { return NO; }
-
- - (BOOL)hasBoundingBox { return NO; }
-
- - (float)lastSampleIsAt { return 0.0; }
-
- - (unsigned long int)maxSampleBandwidth
- {
- unsigned long int maxSampleBandwidth = 0;
- int i, j;
-
-
- if (!n)
- { return maxSampleBandwidth;
- }
- for (i = 0; i < n; i++)
- { maxSampleBandwidth += 1 + strlen(tokens[i]);
- switch (printfTypeVector[i])
- { case WW_FLOAT: maxSampleBandwidth += (printfNVector[i] * sizeof(RtFloat));
- break;
- case WW_COLOR: maxSampleBandwidth += (printfNVector[i] * sizeof(RtFloat));
- break;
- case WW_POINT: maxSampleBandwidth += (printfNVector[i] * sizeof(RtFloat));
- break;
- case WW_INT: maxSampleBandwidth += (printfNVector[i] * sizeof(long));
- break;
- case WW_STRING: for (j = 0; j < printfNVector[i]; j++)
- { maxSampleBandwidth += 1 + strlen(*((char **)(parms[i]) + j));
- }
- break;
- }
- }
- return maxSampleBandwidth;
- }
-
- - deriveHowManyPoints:(char *)archiveStr ofLength:(int)divisor
- {
- char howManyStr[32];
-
-
- // the string looks like "[1234f]"
- strcpy(howManyStr, (archiveStr + 1));
- howManyStr[strlen(howManyStr) - 2] = '\0';
- howManyPoints = atoi(howManyStr) / divisor;
-
- return self;
- }
-
- - (BOOL)isMoot { return NO; }
- - (BOOL)isMootStartingAt:(float)startTime endingAt:(float)endTime { return [self isMoot]; }
-
- // this routine, on the other hand, should be called by subclasses implementing -theSameAs:
- - (BOOL)theSameAs:otherRIBCommand
- {
- int i, j;
- RtToken *tokens2;
- RtPointer *parms2;
- int *printfNVector2;
- int *printfTypeVector2;
-
-
- if ([self class] != [otherRIBCommand class])
- { return NO;
- }
-
- if (n != [otherRIBCommand n])
- { return NO;
- }
-
- tokens2 = [otherRIBCommand tokens];
- parms2 = [otherRIBCommand parms];
- printfNVector2 = [otherRIBCommand printfNVector];
- printfTypeVector2 = [otherRIBCommand printfTypeVector];
-
- // note that there is a false (but probably okay) assumption here
- // that the parameters are in the same order. This doesn't have to be
- // true, but for my stuff, probably will be true.
- for (i = 0; i < n; i++)
- { if (tokens[i] != tokens2[i])
- { if (strcmp(tokens[i], tokens2[i]))
- { return NO;
- }
- }
-
- switch (printfTypeVector[i])
- { case WW_FLOAT: if (printfNVector[i] != printfNVector2[i])
- { return NO;
- }
- for (j = 0; j < printfNVector[i]; j++)
- { if (*((RtFloat *)(parms[i]) + j) != *((RtFloat *)(parms2[i]) + j))
- return NO;
- }
- break;
- case WW_COLOR: if (printfNVector[i] != printfNVector2[i])
- { return NO;
- }
- for (j = 0; j < printfNVector[i]; j++)
- { if (*((RtFloat *)(parms[i]) + j) != *((RtFloat *)(parms2[i]) + j))
- return NO;
- }
- break;
- case WW_POINT: if (printfNVector[i] != printfNVector2[i])
- { return NO;
- }
- for (j = 0; j < printfNVector[i]; j++)
- { if (*((RtFloat *)(parms[i]) + j) != *((RtFloat *)(parms2[i]) + j))
- return NO;
- }
- break;
- case WW_INT: if (printfNVector[i] != printfNVector2[i])
- { return NO;
- }
- for (j = 0; j < printfNVector[i]; j++)
- { if (*((RtInt *)(parms[i]) + j) != *((RtInt *)(parms2[i]) + j))
- return NO;
- }
- break;
- case WW_STRING: if (printfNVector[i] != printfNVector2[i])
- { return NO;
- }
- for (j = 0; j < printfNVector[i]; j++)
- { if (strcmp(*((char **)(parms[i]) + j), *((char **)(parms2[i]) + j)))
- return NO;
- }
- break;
- }
- }
- return YES;
- }
-
-
-
- - (BOOL)similarTo:otherRIBCommand
- {
- if ([self class] != [otherRIBCommand class])
- { return NO;
- }
- if (n != [otherRIBCommand n])
- { return NO;
- }
- return YES;
- }
-
-
- - calculateBoundingBoxStartingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- int i = 0, j = 1;
- BOOL notFound = YES;
- RtFloat *aPointPtr;
-
-
- while (notFound && (i < n))
- { if (!strcmp(tokens[i], "P"))
- { notFound = NO;
- aPointPtr = (RtFloat *)(parms[i]);
- boundingBox[0] = aPointPtr[0];
- boundingBox[1] = aPointPtr[0];
- boundingBox[2] = aPointPtr[1];
- boundingBox[3] = aPointPtr[1];
- boundingBox[4] = aPointPtr[2];
- boundingBox[5] = aPointPtr[2];
- if (!howManyPoints)
- { [self deriveHowManyPoints:archiveVector[i] ofLength:3];
- }
- while (j++ < howManyPoints)
- { if (aPointPtr[0] < boundingBox[0]) { boundingBox[0] = aPointPtr[0]; }
- if (aPointPtr[0] > boundingBox[1]) { boundingBox[1] = aPointPtr[0]; }
- if (aPointPtr[1] < boundingBox[2]) { boundingBox[2] = aPointPtr[1]; }
- if (aPointPtr[1] > boundingBox[3]) { boundingBox[3] = aPointPtr[1]; }
- if (aPointPtr[2] < boundingBox[4]) { boundingBox[4] = aPointPtr[2]; }
- if (aPointPtr[2] > boundingBox[5]) { boundingBox[5] = aPointPtr[2]; }
- aPointPtr += 3;
- }
- }
- if (!strcmp(tokens[i], "Pz"))
- { notFound = NO;
- aPointPtr = (RtFloat *)(parms[i]);
- boundingBox[0] = 0.0;
- boundingBox[1] = 1.0;
- boundingBox[2] = 0.0;
- boundingBox[3] = 1.0;
- boundingBox[4] = aPointPtr[0];
- boundingBox[5] = aPointPtr[0];
- if (!howManyPoints)
- { [self deriveHowManyPoints:archiveVector[i] ofLength:1];
- }
- while (j++ < howManyPoints)
- { if (aPointPtr[0] < boundingBox[4]) { boundingBox[4] = aPointPtr[0]; }
- if (aPointPtr[0] > boundingBox[5]) { boundingBox[5] = aPointPtr[0]; }
- aPointPtr++;
- }
- }
- if (!strcmp(tokens[i], "Pw"))
- { notFound = NO;
- aPointPtr = (RtFloat *)(parms[i]);
- boundingBox[0] = ((aPointPtr[0]) / (aPointPtr[3]));
- boundingBox[1] = ((aPointPtr[1]) / (aPointPtr[3]));
- boundingBox[2] = ((aPointPtr[2]) / (aPointPtr[3]));
- boundingBox[3] = ((aPointPtr[0]) / (aPointPtr[3]));
- boundingBox[4] = ((aPointPtr[1]) / (aPointPtr[3]));
- boundingBox[5] = ((aPointPtr[2]) / (aPointPtr[3]));
- if (!howManyPoints)
- { [self deriveHowManyPoints:archiveVector[i] ofLength:4];
- }
- while (j++ < howManyPoints)
- { if ((aPointPtr[0]/aPointPtr[3]) < boundingBox[0])
- { boundingBox[0] = (aPointPtr[0]/aPointPtr[3]);
- }
- if ((aPointPtr[0]/aPointPtr[3]) > boundingBox[1])
- { boundingBox[1] = (aPointPtr[0]/aPointPtr[3]);
- }
- if ((aPointPtr[1]/aPointPtr[3]) < boundingBox[2])
- { boundingBox[2] = (aPointPtr[1]/aPointPtr[3]);
- }
- if ((aPointPtr[1]/aPointPtr[3]) > boundingBox[3])
- { boundingBox[3] = (aPointPtr[1]/aPointPtr[3]);
- }
- if ((aPointPtr[2]/aPointPtr[3]) < boundingBox[4])
- { boundingBox[4] = (aPointPtr[2]/aPointPtr[3]);
- }
- if ((aPointPtr[2]/aPointPtr[3]) > boundingBox[5])
- { boundingBox[5] = (aPointPtr[2]/aPointPtr[3]);
- }
- aPointPtr += 4;
- }
- }
- i++;
- }
-
- if (notFound)
- { NXLogError("unable to find any points token (RI_P, RI_Z, RI_PW) for %s - can't calculate bounding box...", [[self class] name]);
- return nil;
- }
- dirtyBoundingBox = FALSE;
- return self;
- }
-
-
- - setBoundingBox:(RtBound *)newBoundingBox
- {
- N3D_CopyBound(*newBoundingBox, boundingBox);
-
- return self;
- }
-
- - getBoundingBox:(RtBound *)boundingBoxContainer
- {
- N3D_CopyBound(boundingBox, *boundingBoxContainer);
-
- return self;
- }
-
- - (RtBound *)boundingBoxStartingAt:(RtFloat)intervalStartTime endingAt:(RtFloat)intervalEndTime
- {
- if (dirtyBoundingBox)
- { [self calculateBoundingBoxStartingAt:intervalStartTime endingAt:intervalEndTime];
- }
- return &boundingBox;
- }
-
- - setMyShape:shape { myShape = shape; return self; }
-
- - shape { return myShape; }
-
- - (int)n { return n; }
- - (RtToken *)tokens { return tokens; }
- - (RtPointer *)parms { return parms; }
- - (char **)archiveVector { return archiveVector; }
- - (int *)printfNVector { return printfNVector; }
- - (int *)printfTypeVector { return printfTypeVector; }
-
- - renderMaps:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime usingStream:(NXStream *)ns
- {
- return self;
- }
-
- - renderMaps:(WW3DCamera *)camera usingStream:(NXStream *)ns
- {
- RtFloat shutterOpenTime = [camera shutterOpenTime],
- shutterCloseTime = [camera shutterCloseTime];
-
-
- return [self renderMaps:camera startingAt:shutterOpenTime endingAt:shutterCloseTime usingStream:(NXStream *)ns];
- }
-
- - renderMaps:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- return self;
- }
-
- - renderMaps:(WW3DCamera *)camera
- {
- RtFloat shutterOpenTime = [camera shutterOpenTime],
- shutterCloseTime = [camera shutterCloseTime];
-
-
- return [self renderMaps:camera startingAt:shutterOpenTime endingAt:shutterCloseTime];
- }
-
- - renderSelfAsBox:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- if ([self hasBoundingBox])
- { // if I have a bounding box, don't render myself
- }
- else
- { // otherwise, render myself like normal
- [self renderSelf:camera startingAt:shutterOpenTime endingAt:shutterCloseTime];
- }
-
- // the idea here is that if it has a boundingBox, we don't want to
- // render it (since it has some real geometry, and the whole point of
- // this routine is to avoid drawing geometry). If, on the other hand, it
- // doesn't have a bounding box, it (at most) just transforms the current
- // transformation matrix.
-
- return self;
- }
-
-
- - renderSelf:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- char comment[256];
-
- sprintf(comment, "RIBCommand subclass %s called", [self name]);
- RiArchiveRecord("comment", comment);
- return self;
- }
-
- - renderSelf:(WW3DCamera *)camera
- {
- RtFloat shutterOpenTime = [camera shutterOpenTime],
- shutterCloseTime = [camera shutterCloseTime];
-
-
- return [self renderSelf:camera startingAt:shutterOpenTime endingAt:shutterCloseTime];
- }
-
- - preRenderSelf:(WW3DCamera *)camera startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime
- {
- RiArchiveRecord("comment", "RIBCommand called");
- return self;
- }
-
- - preRenderSelf:(WW3DCamera *)camera
- {
- RtFloat shutterOpenTime = [camera shutterOpenTime],
- shutterCloseTime = [camera shutterCloseTime];
-
-
- return [self renderSelf:camera startingAt:shutterOpenTime endingAt:shutterCloseTime];
- }
-
- - transformCTM:(WW3DAttributeState *)attributeState startingAt:(RtFloat)shutterOpenTime endingAt:(RtFloat)shutterCloseTime { return self; }
-
- - (BOOL)isMotionBlurrable { return NO; }
-
- - (BOOL)isCompoundCommand { return NO; }
-
- - (BOOL)isLerpable { return NO; }
-
- - (const char *)getInspectorClassName { return "RIBCommandIBInspector"; }
-
- // WavesWorld archiving:
- // writeEve:(NXStream *)stream
- // writeScene:(NXStream *)stream
-
- - writeEve:(NXStream *)stream atTabLevel:(int)tab
- {
- int i;
-
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, "#RIBCommand %s called;", [self name]);
- return self;
- }
-
- - writeScene:(NXStream *)stream atTabLevel:(int)tab
- {
- return [self writeEve:stream atTabLevel:tab];
- }
-
-
- - write3DTextScene:(NXStream *)stream atTabLevel:(int)tab index:(int)index time:(float)time until:(float)lastTime
- {
- int i;
-
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
-
- NXPrintf(stream, "set __text__(color%s) {1 1 1}\n", [[self class] name]);
- NXPrintf(stream, "startShape %s; EveCmd {Color $__text__(color%s)}; ", [[self class] name], [[self class] name]);
- // need tab
- // need index (position in current list)
- NXPrintf(stream,
- "EveCmd {Translate [expr { %d * $__text__(tabLength)}] [expr {$__text__(spacingFactor) * %d * $__text__(spacing) * $__text__(fontSize)}] 0 };\n",
- tab, index);
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, " EveCmd {WW3DText $__text__(fontName) $__text__(fontSize) {");
- [self writeEve:stream atTabLevel:tab];
- NXPrintf(stream, "} left;}\n");
- NXPrintf(stream, "endShape;\n");
-
- return self;
- }
-
-
- // this is a routine for subclasses to call when archiving themselves to an Inventor file...
- - writeParameterListForInventor:(NXStream *)stream atTabLevel:(int)tab
- {
- int i, j, k;
-
-
- if (!n)
- { return nil;
- }
-
- // so what's the best way to do this? basically, since Inventor is
- // pretty restricted in what it can support, we need to examine each
- // token, see if it's one that Inventor supports, and if so, spit it out.
-
- // so what does Inventor support?
- // basically, we want to be able to map the following:
- // "P" -> Coordinate3
- // "Pw" -> Coordinate4
- // "N" -> Normal
- // "st" -> TextureCoordinate2
- // "s" "t" -> need to scan for both and generate TextureCoordinate2
-
- for (i = 0; i < n; i++)
- {
- if (!strcmp("P", tokens[i]))
- {
- // I can't think of any reason that there wouldn't at least
- // two points, which the following assumes, but if there's
- // not, I should catch it and do the right thing, sigh...
- if (printfNVector[i] < 6)
- { for (k = 0; k < tab; k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "# less than 2 points - unable to convert RenderMan P token to Inventor Coordinate3 node!\n");
- break;
- }
-
- j = 0;
-
- // write node name and first point
- for (k = 0; k < tab; k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "Coordinate3 {\n");
- for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "point [%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f,\n", *((RtFloat *)(parms[i]) + j)); j++;
-
- // loop over the points, writing them out
- while (j < (printfNVector[i] - 3))
- { for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, " %f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f,\n", *((RtFloat *)(parms[i]) + j)); j++;
- }
-
- // finish up with the last one
- for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, " %f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f]\n", *((RtFloat *)(parms[i]) + j)); j++;
-
- // okay, cap it off and move on
- for (k = 0; k < tab; k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "}\n", *((RtFloat *)(parms[i]) + j)); j++;
- break;
- }
-
- if (!strcmp("Pw", tokens[i]))
- {
- // I can't think of any reason that there wouldn't at least
- // two points, which the following assumes, but if there's
- // not, I should catch it and do the right thing, sigh...
- if (printfNVector[i] < 8)
- { for (k = 0; k < tab; k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "# less than 2 points - unable to convert RenderMan Pw token to Inventor Coordinate4 node!\n");
- break;
- }
-
- j = 0;
-
- // write node name and first point
- for (k = 0; k < tab; k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "Coordinate4 {\n");
- for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "point [%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f,\n", *((RtFloat *)(parms[i]) + j)); j++;
-
- // loop over the points, writing them out
- while (j < (printfNVector[i] - 4))
- { for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, " %f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f,\n", *((RtFloat *)(parms[i]) + j)); j++;
- }
-
- // finish up with the last one
- for (k = 0; k < (tab+1); k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, " %f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j)); j++;
- NXPrintf(stream, "%f]\n", *((RtFloat *)(parms[i]) + j)); j++;
-
- // okay, cap it off and move on
- for (k = 0; k < tab; k++) { NXPrintf(stream, "\t"); }
- NXPrintf(stream, "}\n", *((RtFloat *)(parms[i]) + j)); j++;
- break;
- }
- }
- return self;
- }
-
- - writeInventorAtTime:(float)currentTime to:(NXStream *)stream atTabLevel:(int)tab
- {
- int i;
-
-
- for (i = 0; i < tab; i++)
- { NXPrintf(stream, "\t");
- }
- NXPrintf(stream, "# RIBCommand %s called;", [[self class] name]);
- return self;
-
- }
-
-
- // this is a routine for subclasses to call when archiving themselves to an eve file or a scene...
- - writeParameterList:(NXStream *)stream
- {
- int i, j;
-
-
- if (!n)
- { NXPrintf(stream, ";");
- return nil;
- }
- for (i = 0; i < n; i++)
- { NXPrintf(stream, "{%s} ", tokens[i]);
- switch (printfTypeVector[i])
- { case WW_FLOAT: NXPrintf(stream, "{ ");
- for (j = 0; j < printfNVector[i]; j++)
- { NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j));
- }
- NXPrintf(stream, "} ");
- break;
- case WW_COLOR: NXPrintf(stream, "{ ");
- for (j = 0; j < printfNVector[i]; j++)
- { NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j));
- }
- NXPrintf(stream, "} ");
- break;
- case WW_POINT: NXPrintf(stream, "{ ");
- for (j = 0; j < printfNVector[i]; j++)
- { NXPrintf(stream, "%f ", *((RtFloat *)(parms[i]) + j));
- }
- NXPrintf(stream, "} ");
- break;
- case WW_INT: NXPrintf(stream, "{ ");
- for (j = 0; j < printfNVector[i]; j++)
- { NXPrintf(stream, "%d ", *((int *)(parms[i]) + j));
- }
- NXPrintf(stream, "} ");
- break;
- case WW_STRING: for (j = 0; j < printfNVector[i]; j++)
- { NXPrintf(stream, "{%s} ", *((char **)(parms[i]) + j));
- }
- break;
- }
- }
- NXPrintf(stream, ";");
- return self;
- }
-
-
-
- // NeXTSTEP archiving:
-
- #define typeVector "i"
- #define typeValues &n
-
- - read:(NXTypedStream*)stream
- {
- int version, i, arrayLength;
-
-
- [super read:stream];
-
- version = NXTypedStreamClassVersion(stream,"RIBCommand");
- if (version == 0) NXReadTypes(stream,"i",&version), version=1;
- if (version == 1)
- { NXReadArray(stream, "f", 6, boundingBox);
- NXReadTypes(stream, typeVector, typeValues);
- myShape = NXReadObject(stream);
- NX_DURING
- if (n)
- { if ([self zone])
- { tokens = (char **)NXZoneMalloc([self zone], sizeof(char *) * n);
- archiveVector = (char **)NXZoneMalloc([self zone], sizeof(char *) * n);
- parms = (RtPointer *)NXZoneMalloc([self zone], sizeof(RtPointer) * n);
- }
- else
- { tokens = (char **)malloc(sizeof(char *) * n);
- archiveVector = (char **)malloc(sizeof(char *) * n);
- parms = (RtPointer *)malloc(sizeof(RtPointer) * n);
- }
- for (i = 0; i < n; i++)
- { //NXLogError("RIBCommand: attempting to read token[%d] and archiveVector[%d] of %d...\n", i, i, n);
- NXReadTypes(stream, "**", &(tokens[i]), &(archiveVector[i]));
- //NXLogError("RIBCommand: read: tokens[%d] == <%s> archiveVector[%d] == <%s>\n",
- // i, tokens[i], i, archiveVector[i]);
- //NXLogError("RIBCommand: got 'em!\n");
- //NXLogError("RIBCommand: attempting to read parm[%d] using archiveVector <%s>...\n", i, archiveVector[i]);
-
- // archiveVector is of the form [%df] or [%di]
- // therefore, we can check the second to last character, and key off that
- if (*(archiveVector[i] + strlen(archiveVector[i]) - 2) == 'f')
- { // it's a float
- sscanf(archiveVector[i], "[%df]", &arrayLength);
- if ([self zone])
- { parms[i] = (float *)NXZoneMalloc([self zone], sizeof(float) * arrayLength);
- }
- else
- { parms[i] = (float *)malloc(sizeof(float) * arrayLength);
- }
- if (!parms[i])
- { NXLogError("Yikes! Unable to allocate %d bytes in read: for %s\n",
- (sizeof(float) * arrayLength), [[self class] name]);
- }
- else
- { NXReadArray(stream, "f", arrayLength, parms[i]);
- }
- }
- else
- { if (*(archiveVector[i] + strlen(archiveVector[i]) - 2) == 'i')
- { // it's an integer
- sscanf(archiveVector[i], "[%di]", &arrayLength);
- if ([self zone])
- { parms[i] = (int *)NXZoneMalloc([self zone], sizeof(int) * arrayLength);
- }
- else
- { parms[i] = (int *)malloc(sizeof(int) * arrayLength);
- }
- if (!parms[i])
- { NXLogError("Yikes! Unable to allocate %d bytes in read: for %s\n",
- (sizeof(int) * arrayLength), [[self class] name]);
- }
- else
- { NXReadArray(stream, "i", arrayLength, parms[i]);
- }
- }
- else
- { NXLogError("unable to decipher archiveVector[%d] == %s - didn't read the corresponding data\n", i, archiveVector[i]);
- }
- }
- //NXLogError("RIBCommand: got it!\n");
- }
- }
- NX_HANDLER
- NXLogError("in read:'ing the parameter list for RIBCommand, the subclass %s, exception [%d] raised where i == %d (n == %d).\n",
- [[self class] name], NXLocalHandler.code, i, n);
- return nil;
- NX_ENDHANDLER
- }
-
- return self;
- }
-
- - write:(NXTypedStream*)stream
- {
- int i, arrayLength;
-
-
- [super write:stream];
-
- NXWriteArray(stream, "f", 6, boundingBox);
- NXWriteTypes(stream,typeVector, typeValues);
- NXWriteObjectReference(stream, myShape);
- NX_DURING
- for (i = 0; i < n; i++)
- { //NXLogError("RIBCommand: write: tokens[%d] == <%s> archiveVector[%d] == <%s>\n",
- // i, tokens[i], i, archiveVector[i]);
- NXWriteTypes(stream, "**", &(tokens[i]), &(archiveVector[i]));
-
- // archiveVector is of the form [%df] or [%di]
- // therefore, we can check the second to last character, and key off that
- if (*(archiveVector[i] + strlen(archiveVector[i]) - 2) == 'f')
- { // it's a float
- sscanf(archiveVector[i], "[%df]", &arrayLength);
- NXWriteArray(stream, "f", arrayLength, parms[i]);
- }
- else
- { if (*(archiveVector[i] + strlen(archiveVector[i]) - 2) == 'i')
- { // it's an integer
- sscanf(archiveVector[i], "[%di]", &arrayLength);
- NXWriteArray(stream, "i", arrayLength, parms[i]);
- }
- else
- { NXLogError("unable to decipher archiveVector[%d] == %s - didn't write the corresponding data\n", i, archiveVector[i]);
- }
- }
- }
- NX_HANDLER
- NXLogError("in write:'ing the parameter list for RIBCommand, the subclass %s, exception [%d] raised where i == %d (n == %d).\n",
- [[self class] name], NXLocalHandler.code, i, n);
- return nil;
- NX_ENDHANDLER
-
- return self;
- }
-
-
- // boy, this is dumb... This is to get around the stupid warnings from the compiler - ask wave for details
- - class { return [super class]; }
-
- @end
-